/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
    if (arguments.length === 0 || !time) {
        return null;
    }
    const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
    let date;
    if (typeof time === 'object') {
        date = time;
    } else {
        if ((typeof time === 'string')) {
            if ((/^[0-9]+$/.test(time))) {
                // support "1548221490638"
                time = parseInt(time);
            } else {
                // support safari
                // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
                time = time.replace(new RegExp(/-/gm), '/');
            }
        }

        if ((typeof time === 'number') && (time.toString().length === 10)) {
            time = time * 1000;
        }
        date = new Date(time);
    }
    const formatObj = {
        y: date.getFullYear(),
        m: date.getMonth() + 1,
        d: date.getDate(),
        h: date.getHours(),
        i: date.getMinutes(),
        s: date.getSeconds(),
        a: date.getDay()
    };
    const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
        const value = formatObj[key];
        // Note: getDay() returns 0 on Sunday
        if (key === 'a') {
            return ['日', '一', '二', '三', '四', '五', '六'][value];
        }
        return value.toString().padStart(2, '0');
    });
    return time_str;
}

/**
 * @desc 秒转 hh:mm:ss
 * @param result - 秒数
 * @returns {{sec: (string|number), min: (string|number), hour: (string|number), time: string}}
 */
export function secondToTime(result) {
    var h = Math.floor(result / 3600) < 10 ? '0' + Math.floor(result / 3600) : Math.floor(result / 3600);
    var m = Math.floor((result / 60 % 60)) < 10 ? '0' + Math.floor((result / 60 % 60)) : Math.floor((result / 60 % 60));
    var mm = Math.floor((result / 60)) < 10 ? '0' + Math.floor((result / 60)) : Math.floor((result / 60));
    var s = Math.floor((result % 60)) < 10 ? '0' + Math.floor((result % 60)) : Math.floor((result % 60));
    return { time: h + ':' + m + ':' + s, mins: mm + ':' + s, hour: h, min: m, sec: s }
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
    if (('' + time).length === 10) {
        time = parseInt(time) * 1000;
    } else {
        time = +time;
    }
    const d = new Date(time);
    const now = Date.now();

    const diff = (now - d) / 1000;

    if (diff < 30) {
        return '刚刚';
    } else if (diff < 3600) {
        // less 1 hour
        return Math.ceil(diff / 60) + '分钟前';
    } else if (diff < 3600 * 24) {
        return Math.ceil(diff / 3600) + '小时前';
    } else if (diff < 3600 * 24 * 2) {
        return '1天前';
    }
    if (option) {
        return parseTime(time, option);
    } else {
        return (
            d.getMonth() +
            1 +
            '月' +
            d.getDate() +
            '日' +
            d.getHours() +
            '时' +
            d.getMinutes() +
            '分'
        );
    }
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
    const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ');
    if (!search) {
        return {};
    }
    const obj = {};
    const searchArr = search.split('&');
    searchArr.forEach(v => {
        const index = v.indexOf('=');
        if (index !== -1) {
            const name = v.substring(0, index);
            const val = v.substring(index + 1, v.length);
            obj[name] = val;
        }
    });
    return obj;
}

/**
 * 组合链接
 * @param url
 * @returns {string}
 */
export function remakeUrl(url) {
    return process.env.VUE_APP_BASE_API + url;
}

/**
 * 数组元素移动
 * @param arr {Array}
 * @param $index {number}
 * @param step {number}
 * @return {Array}
 */
export function arrMove(arr, $index, step) {
    // 交换数组元素
    var swapItems = function(arr, index1, index2) {
        arr[index1] = arr.splice(index2, 1, arr[index1])[0];
        return arr;
    };

    // 上移
    if (step === -1) {
        if ($index == 0) {
            return arr;
        }
        swapItems(arr, $index, $index - 1);
    } else if (step === 1) {
        if ($index == arr.length - 1) {
            return arr;
        }
        swapItems(arr, $index, $index + 1);
    } else if (step === -2) {
        arr.unshift(arr.splice($index, 1));
    } else if (step === 2) {
        arr.push(arr.splice($index, 1));
    }
    return arr;
}

/**
 * 检查为空
 * @param str
 * @returns {boolean}
 */
export function isEmpty(str) {
    if (Object.prototype.toString.call(str) === '[object Undefined]') {
        return true
    } else if (
        Object.prototype.toString.call(str) === '[object String]' ||
        Object.prototype.toString.call(str) === '[object Array]') {
        return str.length === 0
    } else if (Object.prototype.toString.call(str) === '[object Object]') {
        return JSON.stringify(str) == '{}'
    } else if (Object.prototype.toString.call(str) === '[object Number]') {
        return str.toString().length == 0
    } else {
        return true
    }
}

/**
 * @desc 函数防抖
 * @param fc 函数
 * @param time 延迟
 * @param isfront 是否首次执行
 * @returns {function(): void}
 */
export function debounce(fc, time, isfront) {
    let timeout;
    return function() {
        if (timeout) {
            clearTimeout(timeout)
        }
        if (isfront) {
            const now = !timeout
            timeout = setTimeout(() => {
                timeout = false
            }, time)
            if (now) {
                fc.apply()
            }
        } else {
            timeout = setTimeout(() => {
                fc.apply()
            }, time)
        }
    }
}

// 驼峰转下划线
export function toLine(name) {
    return name.replace(/([A-Z])/g, '_$1').toLowerCase();
}

// 下划线转驼峰
export function toHump(name) {
    // 把所有大写转为小写
    name = name.toLowerCase();
    return name.replace(/\_(\w)/g, function(all, letter) {
        return letter.toUpperCase();
    });
}

// 根据文件名判断文件类型
export function checkFileType(name) {
    name = name.toLowerCase().split('.').pop();
    if (['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'psd', 'svg', 'tiff'].includes(name)) {
        return 'image'
    } else if (['mp4', 'avi', 'mov', 'rmvb', 'rm', 'flv', '3gp'].includes(name)) {
        return 'video'
    }
    return 'file'
}

/**
 * @desc 通用格式化函数
 * @param field - 检查字段
 * @param list - 检查数组
 * @param value - 检查 value
 * @param label - 返回 label
 * @returns {string}
 */
export function formatter(field, list, label = 'label', value = 'value') {
    const target = list.find(item => field == item[value]) || {}
    return target[label] || ''
}
